﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.IO;

namespace DeepTime.DataSources.DL
{
    public class DeepZoomImageDataSource : IDataSource<CloudBlockBlob>
    {
        #region Class Members
        
        private CloudBlobClient _BlobClient;
        private CloudBlobContainer _BlobContainer;

        #endregion Class Members

        #region Constructors

        public DeepZoomImageDataSource()
        {
            CloudStorageAccount StorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
            _BlobClient = StorageAccount.CreateCloudBlobClient();
            _BlobContainer = _BlobClient.GetContainerReference("deepzoomimages");

            //
            // This should be optimized at a later stage since you don't need to check the table exists EVERY time an instance of the data source is created.
            //
            if (_BlobContainer.CreateIfNotExist())
            {
                BlobContainerPermissions blobContainerPermissions = new BlobContainerPermissions();
                blobContainerPermissions.PublicAccess = BlobContainerPublicAccessType.Off;
                _BlobContainer.SetPermissions(blobContainerPermissions);
            }
        }

        #endregion Constructors

        #region Methods

        public CloudBlobDirectory GetDirectoryReference(string BlobUID)
        {
            return _BlobContainer.GetDirectoryReference(BlobUID);
        }

        public IEnumerable<CloudBlockBlob> Select()
        {
            //IEnumerable<CloudBlockBlob> results = from b in _BlobContainer.ListBlobs(new BlobRequestOptions() { UseFlatBlobListing = true })
            //                                      select _BlobClient.GetBlockBlobReference(b.Uri.OriginalString);
            //return results;
            throw new NotImplementedException();
        }

        public CloudBlockBlob Select(string BlobUID)
        {

            return _BlobContainer.GetBlockBlobReference(BlobUID);
        }

        public void Delete(CloudBlockBlob DataModelToDelete)
        {
            throw new NotImplementedException();
        }

        public void Insert(CloudBlockBlob DataModel)
        {
            throw new NotImplementedException();
        }

        public void Insert(Stream InputStream, string BlobUID, out CloudBlockBlob Blob)
        {
            //
            // Create new Blob
            //
            Blob = _BlobContainer.GetBlockBlobReference(BlobUID);

            //
            // Write to blob
            //
            byte[] buffer = new byte[(4 * 1024 * 1024)];
            int bytesRead;

            int blockID = 0;
            List<string> blockList = new List<string>();
            while ((bytesRead = InputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                string bID = Convert.ToBase64String(BitConverter.GetBytes(blockID));
                MemoryStream ms = new MemoryStream(buffer, 0, bytesRead);

                Blob.PutBlock(bID, ms, null);
                blockList.Add(bID);
                blockID++;
            }

            Blob.PutBlockList(blockList);
        }

        public void Update(CloudBlockBlob DataModel)
        {
            throw new NotImplementedException();
        }

        #endregion Methods
    }
}
